﻿using System;
using System.Runtime.InteropServices;

namespace PdfSdk.PdfViewer
{
    public class PdfiumNative
    {
        [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPTStr)] string lpFileName);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDFBitmap_GetStride(IntPtr bitmap);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDF_InitLibrary();

        [DllImport("Pdfium.dll")]
        internal static extern uint FPDF_GetDocPermissions(IntPtr document);

        [DllImport("pdfium.dll", CharSet = CharSet.Ansi)]
        internal static extern IntPtr FPDF_LoadCustomDocument(
          [MarshalAs(UnmanagedType.LPStruct)] PdfiumNative.FPDF_FILEACCESS access,
          string password);

        [DllImport("Pdfium.dll", CharSet = CharSet.Ansi)]
        internal static extern IntPtr FPDF_LoadMemDocument(
          SafeHandle data_buf,
          int size,
          string password);

        [DllImport("Pdfium.dll", CharSet = CharSet.Ansi)]
        internal static extern IntPtr FPDF_LoadMemDocument(byte[] data_buf, int size, string password);

        [DllImport("Pdfium.dll", CharSet = CharSet.Ansi)]
        internal static extern IntPtr FPDF_LoadDocument(string path, string password);

        [DllImport("Pdfium.dll", CharSet = CharSet.Ansi)]
        internal static extern PdfiumNative.FPDF_ERR FPDF_GetLastError();

        [DllImport("Pdfium.dll")]
        internal static extern int FPDFText_GetText(
          IntPtr page,
          int start_index,
          int count,
          byte[] result);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDF_LoadPage(IntPtr document, int page_index);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDF_ClosePage(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern uint FPDFImageObj_GetImageDataRaw(
          IntPtr document,
          byte[] buffer,
          uint length);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFText_LoadPage(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFText_ClosePage(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDFText_GetCharIndexAtPos(
          IntPtr text_page,
          double x,
          double y,
          double xTolerance,
          double yTolerance);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFPage_GetObject(IntPtr page, int index);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFBitmap_CreateEx(
          int width,
          int height,
          int format,
          IntPtr first_scan,
          int stride);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDF_RenderPage(
          IntPtr dc,
          IntPtr page,
          int start_x,
          int start_y,
          int size_x,
          int size_y,
          int rotate,
          PdfiumNative.FPDF flags);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDF_RenderPageBitmap(
          IntPtr bitmapHandle,
          IntPtr page,
          int start_x,
          int start_y,
          int size_x,
          int size_y,
          int rotate,
          PdfiumNative.FPDF flags);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFBitmap_Create(int width, int height, int alpha);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDFBitmap_FillRect(
          IntPtr bitmapHandle,
          int left,
          int top,
          int width,
          int height,
          uint color);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFBitmap_Destroy(IntPtr bitmapHandle);

        [DllImport("Pdfium.dll")]
        internal static extern double FPDF_GetPageWidth(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern double FPDF_GetPageHeight(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDF_GetPageCount(IntPtr document);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDF_GetPageSizeByIndex(
          IntPtr document,
          int page_index,
          out double width,
          out double height);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFBitmap_GetBuffer(IntPtr bitmap);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDF_CloseDocument(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDFPage_GetRotation(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDFText_CountChars(IntPtr page);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDFText_GetCharBox(
          IntPtr page,
          int index,
          out double left,
          out double right,
          out double bottom,
          out double top);

        public enum FPDF_ERR : uint
        {
            FPDF_ERR_SUCCESS,
            FPDF_ERR_UNKNOWN,
            FPDF_ERR_FILE,
            FPDF_ERR_FORMAT,
            FPDF_ERR_PASSWORD,
            FPDF_ERR_SECURITY,
            FPDF_ERR_PAGE,
        }

        [Flags]
        public enum FPDF
        {
            ANNOT = 1,
            LCD_TEXT = 2,
            NO_NATIVETEXT = 4,
            GRAYSCALE = 8,
            DEBUG_INFO = 128, // 0x00000080
            NO_CATCH = 256, // 0x00000100
            RENDER_LIMITEDIMAGECACHE = 512, // 0x00000200
            RENDER_FORCEHALFTONE = 1024, // 0x00000400
            PRINTING = 2048, // 0x00000800
            REVERSE_BYTE_ORDER = 16, // 0x00000010
        }

        [StructLayout(LayoutKind.Sequential)]
        public class FPDF_FILEACCESS
        {
            public uint m_FileLen;
            public IntPtr m_GetBlock;
            public IntPtr m_Param;
        }

        public enum PdfRenderFlags
        {
            None = 0,
            Annotations = 1,
            LcdText = 2,
            NoNativeText = 4,
            Grayscale = 8,
            LimitImageCacheSize = 512, // 0x00000200
            ForceHalftone = 1024, // 0x00000400
            ForPrinting = 2048, // 0x00000800
            Transparent = 4096, // 0x00001000
            CorrectFromDpi = 8192, // 0x00002000
        }

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFLink_GetLinkAtPoint(IntPtr page, double x, double y);

        [DllImport("Pdfium.dll")]
        internal static extern IntPtr FPDFLink_GetAction(IntPtr link);

        [DllImport("Pdfium.dll")]
        internal static extern int FPDFAction_GetURIPath(IntPtr document, IntPtr action, [MarshalAs(UnmanagedType.LPArray)] byte[] uri, int buflen);

        [DllImport("Pdfium.dll")]
        internal static extern void FPDF_DeviceToPage(IntPtr page, int start_x, int start_y, int size_x, int size_y, int rotate, int device_x, int device_y, [MarshalAs(UnmanagedType.R8)] out double page_x, [MarshalAs(UnmanagedType.R8)] out double page_y);
    }
}
